package logger

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"sync"
	"time"
)

// SimplifiedComponentLatency 简化的组件延迟记录
type SimplifiedComponentLatency struct {
	Component  string    `json:"component"`
	StartTime  time.Time `json:"start_time"`
	EndTime    time.Time `json:"end_time"`
	Duration   int64     `json:"duration_ms"`
	InstanceID int       `json:"instance_id"`
	Round      int       `json:"round"`
	Epoch      int       `json:"epoch"`
	Success    bool      `json:"success"`
	ErrorMsg   string    `json:"error_msg,omitempty"`
}

// SimplifiedPerformanceMetrics 简化的性能指标
type SimplifiedPerformanceMetrics struct {
	Timestamp time.Time `json:"timestamp"`
	NodeID    int       `json:"node_id"`
	
	// 整体性能指标
	TPS       float64 `json:"tps"`
	Latency   int64   `json:"latency_ms"`
	Epoch     int     `json:"epoch"`
	BatchSize int     `json:"batch_size"`
	TxSize    int     `json:"tx_size"`
	
	// 组件整体延迟
	RBCLatency        ComponentLatencySummary `json:"rbc_latency"`
	ABALatency        ComponentLatencySummary `json:"aba_latency"`
	CommonCoinLatency ComponentLatencySummary `json:"common_coin_latency"`
	CBRLatency        ComponentLatencySummary `json:"cbr_latency"`
	ProofChainLatency ComponentLatencySummary `json:"proof_chain_latency"`
	
	// 系统资源
	MemoryMB  float64 `json:"memory_mb"`
	CPUUsage  float64 `json:"cpu_usage"`
}

// ComponentLatencySummary 组件延迟汇总
type ComponentLatencySummary struct {
	AvgLatency    int64   `json:"avg_latency_ms"`
	MaxLatency    int64   `json:"max_latency_ms"`
	MinLatency    int64   `json:"min_latency_ms"`
	TotalOps      int     `json:"total_operations"`
	SuccessOps    int     `json:"success_operations"`
	FailedOps     int     `json:"failed_operations"`
	SuccessRate   float64 `json:"success_rate"`
}

// SimplifiedPerformanceLogger 简化的性能日志记录器
type SimplifiedPerformanceLogger struct {
	nodeID     int
	logDir     string
	logFile    *os.File
	mu         sync.RWMutex
	interval   time.Duration
	stopChan   chan struct{}
	metrics    []SimplifiedPerformanceMetrics
	
	// 组件延迟跟踪
	componentLatencies map[string][]SimplifiedComponentLatency
	latencyMutex       sync.RWMutex
}

// NewSimplifiedPerformanceLogger 创建简化的性能日志记录器
func NewSimplifiedPerformanceLogger(nodeID int, logDir string, interval time.Duration) (*SimplifiedPerformanceLogger, error) {
	// 确保日志目录存在
	if err := os.MkdirAll(logDir, 0755); err != nil {
		return nil, fmt.Errorf("failed to create log directory: %v", err)
	}

	// 创建日志文件
	logFile := filepath.Join(logDir, fmt.Sprintf("node_%d_simplified_performance.log", nodeID))
	file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		return nil, fmt.Errorf("failed to open log file: %v", err)
	}

	spl := &SimplifiedPerformanceLogger{
		nodeID:             nodeID,
		logDir:             logDir,
		logFile:            file,
		interval:           interval,
		stopChan:           make(chan struct{}),
		metrics:            make([]SimplifiedPerformanceMetrics, 0),
		componentLatencies: make(map[string][]SimplifiedComponentLatency),
	}

	// 启动定期记录
	go spl.periodicLog()

	return spl, nil
}

// RecordComponentLatency 记录组件延迟
func (spl *SimplifiedPerformanceLogger) RecordComponentLatency(component string, startTime, endTime time.Time, instanceID, round, epoch int, success bool, errorMsg string) {
	spl.latencyMutex.Lock()
	defer spl.latencyMutex.Unlock()

	latency := SimplifiedComponentLatency{
		Component:  component,
		StartTime:  startTime,
		EndTime:    endTime,
		Duration:   endTime.Sub(startTime).Milliseconds(),
		InstanceID: instanceID,
		Round:      round,
		Epoch:      epoch,
		Success:    success,
		ErrorMsg:   errorMsg,
	}

	// 添加到组件延迟记录
	if spl.componentLatencies[component] == nil {
		spl.componentLatencies[component] = make([]SimplifiedComponentLatency, 0)
	}
	spl.componentLatencies[component] = append(spl.componentLatencies[component], latency)

	// 保持最近1000条记录
	if len(spl.componentLatencies[component]) > 1000 {
		spl.componentLatencies[component] = spl.componentLatencies[component][len(spl.componentLatencies[component])-1000:]
	}
}

// RecordMetrics 记录性能指标
func (spl *SimplifiedPerformanceLogger) RecordMetrics(tps float64, latency int64, epoch int, batchSize int, txSize int) {
	spl.mu.Lock()
	defer spl.mu.Unlock()

	// 计算组件延迟汇总
	componentSummaries := spl.calculateComponentSummaries()

	metric := SimplifiedPerformanceMetrics{
		Timestamp:          time.Now(),
		NodeID:            spl.nodeID,
		TPS:              tps,
		Latency:          latency,
		Epoch:            epoch,
		BatchSize:        batchSize,
		TxSize:           txSize,
		RBCLatency:       componentSummaries["RBC"],
		ABALatency:       componentSummaries["ABA"],
		CommonCoinLatency: componentSummaries["CommonCoin"],
		CBRLatency:       componentSummaries["CBR"],
		ProofChainLatency: componentSummaries["ProofChain"],
		MemoryMB:         spl.getMemoryUsage(),
		CPUUsage:         spl.getCPUUsage(),
	}

	spl.metrics = append(spl.metrics, metric)
}

// calculateComponentSummaries 计算组件延迟汇总
func (spl *SimplifiedPerformanceLogger) calculateComponentSummaries() map[string]ComponentLatencySummary {
	spl.latencyMutex.RLock()
	defer spl.latencyMutex.RUnlock()

	summaries := make(map[string]ComponentLatencySummary)
	components := []string{"RBC", "ABA", "CommonCoin", "CBR", "ProofChain"}

	for _, component := range components {
		latencies := spl.componentLatencies[component]
		if len(latencies) == 0 {
			summaries[component] = ComponentLatencySummary{}
			continue
		}

		var totalLatency, maxLatency, minLatency int64
		var successOps, failedOps int
		
		totalLatency = 0
		maxLatency = 0
		minLatency = int64(^uint64(0) >> 1) // Max int64
		
		for _, latency := range latencies {
			totalLatency += latency.Duration
			if latency.Duration > maxLatency {
				maxLatency = latency.Duration
			}
			if latency.Duration < minLatency {
				minLatency = latency.Duration
			}
			
			if latency.Success {
				successOps++
			} else {
				failedOps++
			}
		}

		avgLatency := totalLatency / int64(len(latencies))
		successRate := float64(successOps) / float64(len(latencies)) * 100

		summaries[component] = ComponentLatencySummary{
			AvgLatency:   avgLatency,
			MaxLatency:   maxLatency,
			MinLatency:   minLatency,
			TotalOps:     len(latencies),
			SuccessOps:   successOps,
			FailedOps:    failedOps,
			SuccessRate:  successRate,
		}
	}

	return summaries
}

// periodicLog 定期记录日志
func (spl *SimplifiedPerformanceLogger) periodicLog() {
	ticker := time.NewTicker(spl.interval)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			spl.logCurrentMetrics()
		case <-spl.stopChan:
			return
		}
	}
}

// logCurrentMetrics 记录当前指标
func (spl *SimplifiedPerformanceLogger) logCurrentMetrics() {
	spl.mu.RLock()
	defer spl.mu.RUnlock()

	if len(spl.metrics) == 0 {
		return
	}

	// 获取最新的指标
	latest := spl.metrics[len(spl.metrics)-1]

	// 写入日志文件
	logEntry := fmt.Sprintf("[%s] Node-%d: TPS=%.2f, Latency=%dms, Epoch=%d, BatchSize=%d, TxSize=%d\n",
		latest.Timestamp.Format("2006-01-02 15:04:05"),
		latest.NodeID,
		latest.TPS,
		latest.Latency,
		latest.Epoch,
		latest.BatchSize,
		latest.TxSize)

	// 添加组件延迟信息
	logEntry += fmt.Sprintf("  RBC: avg=%dms, max=%dms, ops=%d, success=%.1f%%\n",
		latest.RBCLatency.AvgLatency,
		latest.RBCLatency.MaxLatency,
		latest.RBCLatency.TotalOps,
		latest.RBCLatency.SuccessRate)

	logEntry += fmt.Sprintf("  ABA: avg=%dms, max=%dms, ops=%d, success=%.1f%%\n",
		latest.ABALatency.AvgLatency,
		latest.ABALatency.MaxLatency,
		latest.ABALatency.TotalOps,
		latest.ABALatency.SuccessRate)

	logEntry += fmt.Sprintf("  CommonCoin: avg=%dms, max=%dms, ops=%d, success=%.1f%%\n",
		latest.CommonCoinLatency.AvgLatency,
		latest.CommonCoinLatency.MaxLatency,
		latest.CommonCoinLatency.TotalOps,
		latest.CommonCoinLatency.SuccessRate)

	logEntry += fmt.Sprintf("  CBR: avg=%dms, max=%dms, ops=%d, success=%.1f%%\n",
		latest.CBRLatency.AvgLatency,
		latest.CBRLatency.MaxLatency,
		latest.CBRLatency.TotalOps,
		latest.CBRLatency.SuccessRate)

	logEntry += fmt.Sprintf("  ProofChain: avg=%dms, max=%dms, ops=%d, success=%.1f%%\n",
		latest.ProofChainLatency.AvgLatency,
		latest.ProofChainLatency.MaxLatency,
		latest.ProofChainLatency.TotalOps,
		latest.ProofChainLatency.SuccessRate)

	spl.logFile.WriteString(logEntry)
	spl.logFile.Sync()

	// 同时输出到控制台
	fmt.Print(logEntry)
}

// getMemoryUsage 获取内存使用量 (MB)
func (spl *SimplifiedPerformanceLogger) getMemoryUsage() float64 {
	// 简化实现，实际应该读取 /proc/self/status
	return 0.0
}

// getCPUUsage 获取CPU使用率 (%)
func (spl *SimplifiedPerformanceLogger) getCPUUsage() float64 {
	// 简化实现，实际应该读取 /proc/stat
	return 0.0
}

// ExportMetrics 导出指标到JSON文件
func (spl *SimplifiedPerformanceLogger) ExportMetrics() error {
	spl.mu.RLock()
	defer spl.mu.RUnlock()

	jsonFile := filepath.Join(spl.logDir, fmt.Sprintf("node_%d_simplified_metrics.json", spl.nodeID))
	file, err := os.Create(jsonFile)
	if err != nil {
		return fmt.Errorf("failed to create JSON file: %v", err)
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	encoder.SetIndent("", "  ")
	return encoder.Encode(spl.metrics)
}

// ExportComponentLatencies 导出组件延迟到JSON文件
func (spl *SimplifiedPerformanceLogger) ExportComponentLatencies() error {
	spl.latencyMutex.RLock()
	defer spl.latencyMutex.RUnlock()

	jsonFile := filepath.Join(spl.logDir, fmt.Sprintf("node_%d_component_latencies.json", spl.nodeID))
	file, err := os.Create(jsonFile)
	if err != nil {
		return fmt.Errorf("failed to create component latencies JSON file: %v", err)
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	encoder.SetIndent("", "  ")
	return encoder.Encode(spl.componentLatencies)
}

// Stop 停止日志记录器
func (spl *SimplifiedPerformanceLogger) Stop() {
	close(spl.stopChan)
	spl.logFile.Close()
}

// GetMetrics 获取所有指标
func (spl *SimplifiedPerformanceLogger) GetMetrics() []SimplifiedPerformanceMetrics {
	spl.mu.RLock()
	defer spl.mu.RUnlock()
	return spl.metrics
}

// GetComponentLatencies 获取组件延迟
func (spl *SimplifiedPerformanceLogger) GetComponentLatencies() map[string][]SimplifiedComponentLatency {
	spl.latencyMutex.RLock()
	defer spl.latencyMutex.RUnlock()
	return spl.componentLatencies
}
